#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
MCP接口模块

负责将MCP服务器和客户端整合到agent系统中，处理与外部系统的通信。
"""

import asyncio
import logging
from typing import Dict, Any, Optional, Callable
from mcp.mcp_server import MCPServer
from mcp.mcp_client import MCPClient
from mcp.mcp_protocol import MCPCommand, MCPPacket

logger = logging.getLogger(__name__)


class MCPInterface:
    """MCP接口类"""

    def __init__(self, agent_core, host: str = "0.0.0.0", port: int = 9000):
        """
        初始化MCP接口

        Args:
            agent_core: AgentCore实例
            host: MCP服务器主机地址
            port: MCP服务器端口
        """
        self.agent_core = agent_core
        self.server = MCPServer(host, port)
        self.client = MCPClient(host, port)

        # 注册命令处理器
        self._register_handlers()

    def _register_handlers(self):
        """注册MCP命令处理器"""
        # 注册服务器端处理器
        self.server.register_handler(MCPCommand.COMMAND, self._handle_command)
        self.server.register_handler(
            MCPCommand.STATE_REQUEST, self._handle_state_request
        )

        # 注册客户端处理器
        self.client.register_handler(MCPCommand.STATE_UPDATE, self._handle_state_update)
        self.client.register_handler(
            MCPCommand.ACTION_RESULT, self._handle_action_result
        )

    async def _handle_command(
        self, client_id: str, packet: MCPPacket
    ) -> Optional[MCPPacket]:
        """处理来自客户端的命令"""
        try:
            command = packet.payload.get("command")
            if not command:
                return self.server.protocol.create_error_packet(400, "Missing command")

            # 使用agent处理命令
            result = await self.agent_core.process_command(command)

            # 发送确认响应
            return self.server.protocol.create_ack_packet(packet.header.sequence)

        except Exception as e:
            logger.error(f"处理命令时出错: {e}")
            return self.server.protocol.create_error_packet(500, str(e))

    async def _handle_state_request(
        self, client_id: str, packet: MCPPacket
    ) -> Optional[MCPPacket]:
        """处理状态请求"""
        try:
            state = self.agent_core.get_state()
            return self.server.protocol.create_packet(MCPCommand.STATE_UPDATE, state)
        except Exception as e:
            logger.error(f"获取状态时出错: {e}")
            return self.server.protocol.create_error_packet(500, str(e))

    async def _handle_state_update(self, packet: MCPPacket) -> None:
        """处理状态更新"""
        try:
            state = packet.payload
            # 更新agent状态
            self.agent_core.update_state(state)
        except Exception as e:
            logger.error(f"更新状态时出错: {e}")

    async def _handle_action_result(self, packet: MCPPacket) -> None:
        """处理动作执行结果"""
        try:
            result = packet.payload
            # 更新agent动作结果
            self.agent_core.update_action_result(result)
        except Exception as e:
            logger.error(f"处理动作结果时出错: {e}")

    async def start(self):
        """启动MCP接口"""
        try:
            # 启动服务器
            await self.server.start()
            # 启动客户端
            await this.client.connect()
            # 启动心跳
            asyncio.create_task(this.client.start_heartbeat())

            logger.info("MCP接口已启动")
        except Exception as e:
            logger.error(f"启动MCP接口失败: {e}")
            await this.stop()
            raise

    async def stop(self):
        """停止MCP接口"""
        try:
            # 停止客户端
            await this.client.disconnect()
            # 停止服务器
            await this.server.stop()
            logger.info("MCP接口已停止")
        except Exception as e:
            logger.error(f"停止MCP接口时出错: {e}")

    async def broadcast_state(self):
        """广播当前状态"""
        try:
            state = this.agent_core.get_state()
            packet = this.client.protocol.create_packet(MCPCommand.STATE_UPDATE, state)
            await this.client.send_packet(packet)
        except Exception as e:
            logger.error(f"广播状态时出错: {e}")

    async def send_action_result(self, result: Dict[str, Any]):
        """发送动作执行结果"""
        try:
            packet = this.client.protocol.create_packet(
                MCPCommand.ACTION_RESULT, result
            )
            await this.client.send_packet(packet)
        except Exception as e:
            logger.error(f"发送动作结果时出错: {e}")
